/**
 * JAVACC DEMO 1.0
 * @copy right apache company All rights reserved. 
 * @Package com.apache.rpc.server.impl  
 */
package com.apache.rpc.server.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.apache.api.api.ApiService;
import com.apache.api.api.SystemService.ParamType;
import com.apache.api.entity.BaseEntity;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.cache.util.Validator;
import com.apache.database.constant.SpringContextLoader;
import com.apache.exception.BusinessException;
import com.apache.exception.ServiceException;
import com.apache.rpc.InternalService;
import com.apache.rpc.ProtocolService;
import com.apache.rpc.entity.InterfaceRegister;
import com.apache.rpc.entity.Protocol;
import com.apache.rpc.server.protocl.AbstractProtocolService;
import com.apache.rpc.service.impl.helper.CacheTactics;
import com.apache.rpc.util.XMLMapParse;

/**
 * description:  通信适配器
 * @author Hou Dayu 创建时间：2014-10-28  
 * @Copyright(c)2014:
 */
public class ProtocolAdapter implements ProtocolService {

	private static ProtocolAdapter adapter;
	private CacheTactics interfaceRegisterCacheTactics;
	private InternalService protocolInternalService;
	private Logger log = Logger.getLogger(ProtocolAdapter.class);

	private Map<String, AbstractProtocolService> services = new HashMap<String, AbstractProtocolService>();

	public ProtocolAdapter() {
		adapter = this;
	}

	public static ProtocolAdapter getAdapter() {
		return adapter;
	}

	public void destroy() {
		adapter = null;
	}

	public Object doService(Protocol protocol) {
		String result = "";
		Map<String, List<InterfaceRegister>> list = interfaceRegisterCacheTactics.selectInterfaceRegisterCache(
				protocol.getBeanId(), "1", protocol.getReqFlag());
		InterfaceRegister register = getServiceKey(list, protocol.getProtocolType());
		try {
			if (Validator.isEmpty(register) || "internal".equals(register.getCallType())) {//直接执行本地服务
				ParamsVo<BaseEntity> vo = new ParamsVo<BaseEntity>();
				vo.setParams(protocol.getParams());
				vo.setMethodKey(protocol.getReqFlag());
				return doService(protocol.getBeanId(), vo);
				//SystemService service = (SystemService) SpringContextLoader.getBean("protocol_systemService");
				//				ResultEntity entity = protocolInternalService.doService(params);
				//				return entity;
			} else {
				String params = XMLMapParse.instance().buildSingleXML(protocol);
				ParamType resultType = getParamType(protocol.getRespType());
				AbstractProtocolService ps = services.get(register.getCallType());
				ps.setHttpIp(register.getAddress());
				ps.setHttpUrl(register.getAddress());
				ps.setHttpProt(register.getPort());
				result = services.get(register.getCallType()).doService(params, resultType);
			}
		} catch (Exception e) {
			log.info("接口[" + protocol.getBeanId() + "]执行出错：" + e + ";执行参数：" + protocol.getParams());
			throw new BusinessException("接口[" + protocol.getBeanId() + "]执行出错", e);
		}
		return result;
	}

	public Object doService(String beanId, ParamsVo<BaseEntity> vo) {
		ResultEntity result = null;
		try {
			ApiService service = (ApiService) SpringContextLoader.getBean(beanId);
			result = service.doService(vo);
		} catch (Exception e) {
			log.error(e);
			throw new ServiceException("接口[" + beanId + "]执行出错", e);
		}
		return result;
	}

	private InterfaceRegister getServiceKey(Map<String, List<InterfaceRegister>> list, String type) {
		if (Validator.isEmpty(list))
			return null;
		InterfaceRegister register = null;
		if (!Validator.isEmpty(list.get(type))) {
			return list.get(type).get(0);
		}
		if (!Validator.isEmpty(list.get("internal"))) {
			register = list.get("internal").get(0);
		} else if (!Validator.isEmpty(list.get("socket"))) {
			register = list.get("socket").get(0);
		} else if (!Validator.isEmpty(list.get("webservice"))) {
			register = list.get("webservice").get(0);
		} else if (!Validator.isEmpty(list.get("https"))) {
			register = list.get("https").get(0);
		} else if (!Validator.isEmpty(list.get("http"))) {
			register = list.get("http").get(0);
		}
		return register;
	}

	//	private String getParams(Protocol protocol) {
	//
	//		StringBuffer sb = new StringBuffer(XMLMapParse.instance().buildSingleXML(protocol));
	//		return sb.toString();
	//	}

	private ParamType getParamType(String type) {
		if ("json".equalsIgnoreCase(type)) {
			return ParamType.JSON;
		} else {
			return ParamType.XML;
		}
	}

	public void setServices(Map<String, AbstractProtocolService> services) {
		this.services = services;
	}

	public void setInterfaceRegisterCacheTactics(CacheTactics interfaceRegisterCacheTactics) {
		this.interfaceRegisterCacheTactics = interfaceRegisterCacheTactics;
	}

	public void setProtocolInternalService(InternalService protocolInternalService) {
		this.protocolInternalService = protocolInternalService;
	}

}
